package gulimall.member.service.impl;

import cn.hutool.crypto.digest.DigestUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.ObjectMapper;
import gulimall.member.bo.MemberLoginBO;
import gulimall.member.bo.MemberRegistBO;
import gulimall.member.bo.SocialUserBO;
import gulimall.member.dao.MemberDao;
import gulimall.member.dao.MemberLevelDao;
import gulimall.member.entity.MemberEntity;
import gulimall.member.entity.MemberLevelEntity;
import gulimall.member.exception.PhoneExistException;
import gulimall.member.exception.UsernameExistException;
import gulimall.member.service.MemberService;
import gulimall.member.utils.HttpUtils;
import gulimall.member.vo.GiteeUser;
import gulimall.utils.PageUtils;
import gulimall.utils.Query;
import gulimall.vo.MemberRespVO;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;


@Service("memberService")
public class MemberServiceImpl extends ServiceImpl<MemberDao, MemberEntity> implements MemberService {

    @Resource
    private MemberLevelDao memberLevelDao;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<MemberEntity> page = this.page(
                new Query<MemberEntity>().getPage(params),
                new QueryWrapper<MemberEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public void regist(MemberRegistBO registBO) {
        MemberDao memberDao = this.baseMapper;
        MemberEntity entity = new MemberEntity();

        // 设置默认等级
        MemberLevelEntity memberLevelEntity = memberLevelDao.selectOne(new LambdaQueryWrapper<MemberLevelEntity>()
                .eq(MemberLevelEntity::getDefaultStatus, 1));
        entity.setLevelId(memberLevelEntity.getId());


        // 检查手机号和用户名是否唯一
        checkPhoneUnique(registBO.getPhone());
        checkUserNameUnique(registBO.getUsername());

        entity.setMobile(registBO.getPhone());
        entity.setUsername(registBO.getUsername());
        entity.setNickname(registBO.getUsername());

        //密码要加密存储(使用hutool工具类进行加密)
        String md5Hex = DigestUtil.md5Hex(registBO.getPassword());
        entity.setPassword(md5Hex);

        memberDao.insert(entity);
    }

    @Override
    public void checkPhoneUnique(String phone) throws PhoneExistException {
        MemberDao memberDao = this.baseMapper;
        Integer mobile = Math.toIntExact(memberDao.selectCount(new QueryWrapper<MemberEntity>().eq("mobile", phone)));
        if (mobile > 0) {
            throw new PhoneExistException();
        }
    }

    @Override
    public void checkUserNameUnique(String username) throws UsernameExistException {
        MemberDao memberDao = this.baseMapper;
        Integer count = Math.toIntExact(memberDao.selectCount(new QueryWrapper<MemberEntity>().eq("username", username)));
        if (count > 0) {
            throw new UsernameExistException();
        }
    }

    @Override
    public MemberRespVO memberLogin(MemberLoginBO memberLoginBO) {

        //1.根据用户名或者手机号查询会员用户是否存在
        MemberEntity memberEntity = baseMapper.selectOne(
                new LambdaQueryWrapper<MemberEntity>()
                        .eq(MemberEntity::getUsername, memberLoginBO.getLoginUser())
                        .or()
                        .eq(MemberEntity::getMobile, memberLoginBO.getLoginUser())
        );

        if (memberEntity != null) {
            //2.验证密码是否正确
            String md5Hex = DigestUtil.md5Hex(memberLoginBO.getPassword());
            if (memberEntity.getPassword().equals(md5Hex)) {
                MemberRespVO memberRespVO = new MemberRespVO();
                BeanUtils.copyProperties(memberEntity, memberRespVO);
                return memberRespVO;
            }
        }

        return null;
    }

    /**
     * 会员使用社交账号登录
     *
     * @param socialUserBO
     * @return 返回会员对象实体
     */
    @Override
    @Transactional
    public MemberEntity memberOauth2Login(SocialUserBO socialUserBO) {
        ObjectMapper mapper = new ObjectMapper();

        //根据uId查询数据库判断是否是新用户，
        //如果是新用户就进行注册并进行登录验证，如果不是就进行登录验证

        Long uId = socialUserBO.getUId();
        MemberEntity memberEntity = baseMapper.selectOne(new LambdaQueryWrapper<MemberEntity>()
                .eq(MemberEntity::getUId, uId));

        if (memberEntity != null) {
            //更新该用户的access token，过期时间
            MemberEntity update = new MemberEntity();
            update.setId(memberEntity.getId());
            update.setAccessToken(socialUserBO.getAccess_token());
            update.setExpiresIn(socialUserBO.getExpires_in());

            baseMapper.updateById(update);

            //更新信息后返回会员对象
            memberEntity.setExpiresIn(socialUserBO.getExpires_in());
            memberEntity.setAccessToken(socialUserBO.getAccess_token());
            return memberEntity;
        } else {
            MemberEntity regist = new MemberEntity();
            regist.setAccessToken(socialUserBO.getAccess_token());
            regist.setExpiresIn(socialUserBO.getExpires_in());
            regist.setUId(socialUserBO.getUId());

            //设置会员默认等级
            MemberLevelEntity memberLevelEntity = memberLevelDao.selectOne(new LambdaQueryWrapper<MemberLevelEntity>()
                    .eq(MemberLevelEntity::getDefaultStatus, 1));
            regist.setLevelId(memberLevelEntity.getId());

            try {
                Map<String, String> header = new HashMap<>();
                Map<String, String> body = new HashMap<>();
                body.put("access_token", socialUserBO.getAccess_token());
                HttpResponse response1 = HttpUtils.doGet("https://gitee.com", "/api/v5/user", "get", header, body);
                if (response1.getStatusLine().getStatusCode() == 200) {
                    String json1 = EntityUtils.toString(response1.getEntity());
                    GiteeUser giteeUser = mapper.readValue(json1, GiteeUser.class);

                    regist.setUsername(giteeUser.getName());
                    regist.setNickname(giteeUser.getName());
                    regist.setSign(giteeUser.getBio());//设置个性签名
                    regist.setEmail(giteeUser.getEmail());
                }

                //将该新用户插入到数据库
                baseMapper.insert(regist);
                return regist;

            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }

    }


}